`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    00:13:12 11/20/2020 
// Design Name: 
// Module Name:    ctrl 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
include "defines.v";

module ctrl(
    input [5:0] opCode,
    input [5:0] func,
	 input zero,
    output reg regDst,
    output reg jump,
    output reg jumpReg,
    output reg branch,
    output reg memToReg,
    output reg [4:0] aluOp,
	 output reg [4:0] cmpOp,
    output reg [1:0] extOp,
    output reg memWrite,
    output reg aluSrc,
    output reg regWrite,
    output reg link,
	 output reg PC2Reg
    );
always @*
	case(opCode)
		`special:
		begin
			case (func)
			
				`addu:
				begin
					regDst	<=	0;
					jump		<=	0;
					jumpReg	<= 0;
					branch	<=	0;
					memToReg	<=	0;
					aluOp		<=	`ADDU;
					cmpOp		<= 0;
					extOp		<=	0;
					memWrite	<=	0;
					aluSrc	<=	0;
					regWrite	<=	1;
					link		<=	0;
					PC2Reg	<=	0;
				end
				
				`subu:
				begin
					regDst	<=	0;
					jump		<=	0;
					jumpReg	<= 0;
					branch	<=	0;
					memToReg	<=	0;
					aluOp		<=	`SUBU;
					cmpOp		<= 0;
					extOp		<=	0;
					memWrite	<=	0;
					aluSrc	<=	0;
					regWrite	<=	1;
					link		<=	0;
					PC2Reg	<=	0;
				end
				
				`jr:
				begin
					regDst	<=	0;
					jump		<=	1;
					jumpReg	<= 1;
					branch	<=	0;
					memToReg	<=	0;
					aluOp		<=	0;
					cmpOp		<= 0;
					extOp		<=	0;
					memWrite	<=	0;
					aluSrc	<=	0;
					regWrite	<=	0;
					link		<=	0;
					PC2Reg	<=	0;
				end

				`jalr:
				begin
					regDst	<=	0;
					jump		<=	1;
					jumpReg	<= 1;
					branch	<=	0;
					memToReg	<=	0;
					aluOp		<=	0;
					cmpOp		<= 0;
					extOp		<=	0;
					memWrite	<=	0;
					aluSrc	<=	0;
					regWrite	<=	1;
					link		<=	0;
					PC2Reg	<=	1;
				end

				default:
				begin
					regDst	<=	0;
					jump		<=	0;
					jumpReg	<= 0;
					branch	<=	0;
					memToReg	<=	0;
					aluOp		<=	0;
					cmpOp		<= 0;
					extOp		<=	0;
					memWrite	<=	0;
					aluSrc	<=	0;
					regWrite	<=	0;
					link		<=	0;
					PC2Reg	<=	0;
				end
			endcase
		end
		
		`ori:
		begin
			regDst	<=	1;
			jump		<=	0;
			jumpReg	<= 0;
			branch	<=	0;
			memToReg	<=	0;
			aluOp		<=	`OR;
			cmpOp		<= 0;
			extOp		<=	2'b01;
			memWrite	<=	0;
			aluSrc	<=	1;
			regWrite	<=	1;
			link		<=	0;
			PC2Reg	<=	0;
		end
		
		`addi:
		begin
			regDst	<=	1;
			jump		<=	0;
			jumpReg	<= 0;
			branch	<=	0;
			memToReg	<=	0;
			aluOp		<=	`ADDU;
			cmpOp		<= 0;
			extOp		<=	2'b00;
			memWrite	<=	0;
			aluSrc	<=	1;
			regWrite	<=	1;
			link		<=	0;
			PC2Reg	<=	0;
		end
		
		`lw:
		begin
			regDst	<=	1;
			jump		<=	0;
			jumpReg	<= 0;
			branch	<=	0;
			memToReg	<=	1;
			aluOp		<=	`ADDU;
			cmpOp		<= 0;
			extOp		<=	0;
			memWrite	<=	0;
			aluSrc	<=	1;
			regWrite	<=	1;
			link		<=	0;
			PC2Reg	<=	0;
		end
		
		`sw:
		begin
			regDst	<=	0;
			jump		<=	0;
			jumpReg	<= 0;
			branch	<=	0;
			memToReg	<=	0;
			aluOp		<=	`ADDU;
			cmpOp		<= 0;
			extOp		<=	0;
			memWrite	<=	1;
			aluSrc	<=	1;
			regWrite	<=	0;
			link		<=	0;
			PC2Reg	<=	0;
		end
		
		`beq:
		begin
			regDst	<=	0;
			jump		<=	0;
			jumpReg	<= 0;
			branch	<=	1;
			memToReg	<=	0;
			aluOp		<=	0;
			cmpOp		<= 1;
			extOp		<=	2'b11;
			memWrite	<=	0;
			aluSrc	<=	0;
			regWrite	<=	0;
			link		<=	0;
			PC2Reg	<=	0;
		end
		
		`lui:
		begin
			regDst	<=	1;
			jump		<=	0;
			jumpReg	<= 0;
			branch	<=	0;
			memToReg	<=	0;
			aluOp		<=	`OR;
			cmpOp		<= 0;
			extOp		<=	2'b10;
			memWrite	<=	0;
			aluSrc	<=	1;
			regWrite	<=	1;
			link		<=	0;
			PC2Reg	<=	0;
		end
		
		`jal:
		begin
			regDst	<=	0;
			jump		<=	1;
			jumpReg	<= 0;
			branch	<=	0;
			memToReg	<=	0;
			aluOp		<=	0;
			cmpOp		<= 0;
			extOp		<=	0;
			memWrite	<=	0;
			aluSrc	<=	0;
			regWrite	<=	1;
			link		<=	1;
			PC2Reg	<=	1;
		end
				
		`j:
		begin
			regDst	<=	0;
			jump		<=	1;
			jumpReg	<= 0;
			branch	<=	0;
			memToReg	<=	0;
			aluOp		<=	0;
			cmpOp		<= 0;
			extOp		<=	0;
			memWrite	<=	0;
			aluSrc	<=	0;
			regWrite	<=	0;
			link		<=	0;
			PC2Reg	<=	0;
		end	
				
		default:
		begin
			regDst	<=	0;
			jump		<=	0;
			jumpReg	<= 0;
			branch	<=	0;
			memToReg	<=	0;
			aluOp		<=	0;
			cmpOp		<= 0;
			extOp		<=	0;
			memWrite	<=	0;
			aluSrc	<=	0;
			regWrite	<=	0;
			link		<=	0;
			PC2Reg	<=	0;
		end
	endcase

endmodule
